using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Utilities;

namespace Microsoft.EntityFrameworkCore.Migrations;

public class DmMigrationsSqlGenerator : MigrationsSqlGenerator
{
	public DmMigrationsSqlGenerator([NotNull] MigrationsSqlGeneratorDependencies dependencies, [NotNull] IMigrationsAnnotationProvider migrationsAnnotations)
		: base(dependencies)
	{
	}

	protected override void ColumnDefinition(AddColumnOperation operation, IModel model, MigrationCommandListBuilder builder)
	{
		this.ColumnDefinition(operation.Schema, operation.Table, operation.Name, operation, model, builder);
	}

	protected override void Generate(MigrationOperation operation, IModel model, MigrationCommandListBuilder builder)
	{
		Check.NotNull<MigrationOperation>(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		DmCreateUserOperation dmCreateUserOperation = operation as DmCreateUserOperation;
		if (dmCreateUserOperation != null)
		{
			this.Generate(dmCreateUserOperation, model, builder);
			return;
		}
		DmDropSchemaOperation dmDropSchemaOperation = operation as DmDropSchemaOperation;
		if (dmDropSchemaOperation != null)
		{
			this.Generate(dmDropSchemaOperation, model, builder);
			return;
		}
		DmCreateSchemaOperation dmCreateSchemaOperation = operation as DmCreateSchemaOperation;
		if (dmCreateSchemaOperation != null)
		{
			this.Generate(dmCreateSchemaOperation, model, builder);
			return;
		}
		DmDropUserOperation dmDropUserOperation = operation as DmDropUserOperation;
		if (dmDropUserOperation != null)
		{
			this.Generate(dmDropUserOperation, model, builder);
			return;
		}
		CreateTableOperation createTableOperation = operation as CreateTableOperation;
		if (createTableOperation != null)
		{
			this.Generate(createTableOperation, model, builder, true);
			return;
		}
		base.Generate(operation, model, builder);
	}

	protected override void Generate([NotNull] AlterDatabaseOperation operation, [CanBeNull] IModel model, [NotNull] MigrationCommandListBuilder builder)
	{
		throw new NotSupportedException("AlterDatabaseOperation does not support");
	}

	protected override void Generate([NotNull] CreateSequenceOperation operation, [CanBeNull] IModel model, [NotNull] MigrationCommandListBuilder builder)
	{
		if (operation.ClrType != typeof(long))
		{
			throw new NotSupportedException("CreateSequenceOperation only support long type");
		}
		base.Generate(operation, model, builder);
	}

	protected override void Generate(AlterColumnOperation operation, IModel model, MigrationCommandListBuilder builder)
	{
		Check.NotNull<AlterColumnOperation>(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		if (model != null)
		{
			ITable table = RelationalModelExtensions.GetRelationalModel(model).FindTable(operation.Table, operation.Schema);
			if (table != null)
			{
				table.Columns.FirstOrDefault((IColumn c) => c.Name == operation.Name);
			}
		}
		if (operation.ComputedColumnSql != null)
		{
			DropColumnOperation dropColumnOperation = new DropColumnOperation
			{
				Schema = operation.Schema,
				Table = operation.Table,
				Name = operation.Name
			};
			AddColumnOperation addColumnOperation = new AddColumnOperation
			{
				Schema = operation.Schema,
				Table = operation.Table,
				Name = operation.Name,
				ClrType = operation.ClrType,
				ColumnType = operation.ColumnType,
				IsUnicode = operation.IsUnicode,
				MaxLength = operation.MaxLength,
				IsRowVersion = operation.IsRowVersion,
				IsNullable = operation.IsNullable,
				DefaultValue = operation.DefaultValue,
				DefaultValueSql = operation.DefaultValueSql,
				ComputedColumnSql = operation.ComputedColumnSql,
				IsFixedLength = operation.IsFixedLength,
				Comment = operation.Comment
			};
			addColumnOperation.AddAnnotations(operation.GetAnnotations());
			this.Generate(dropColumnOperation, model, builder, true);
			this.Generate(addColumnOperation, model, builder);
			return;
		}
		bool flag = (operation["Dm:ValueGenerationStrategy"] as DmValueGenerationStrategy?).GetValueOrDefault() == DmValueGenerationStrategy.IdentityColumn;
		if (this.IsOldColumnSupported(model))
		{
			if ((operation.OldColumn["Dm:ValueGenerationStrategy"] as DmValueGenerationStrategy?).GetValueOrDefault() == DmValueGenerationStrategy.IdentityColumn && !flag)
			{
				DmMigrationsSqlGenerator.DropIdentity(operation, builder);
			}
			if (operation.OldColumn.DefaultValue != null || (operation.OldColumn.DefaultValueSql != null && (operation.DefaultValue == null || operation.DefaultValueSql == null)))
			{
				this.DropDefaultConstraint(operation.Schema, operation.Table, operation.Name, builder);
			}
		}
		else
		{
			if (!flag)
			{
				DmMigrationsSqlGenerator.DropIdentity(operation, builder);
			}
			if (operation.DefaultValue == null && operation.DefaultValueSql == null)
			{
				this.DropDefaultConstraint(operation.Schema, operation.Table, operation.Name, builder);
			}
		}
		builder.Append("ALTER TABLE ").Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Table, operation.Schema)).Append(" MODIFY ");
		this.ColumnDefinition(operation.Schema, operation.Table, operation.Name, operation, model, builder);
		builder.AppendLine(this.Dependencies.SqlGenerationHelper.StatementTerminator);
		builder.EndCommand(false);
		if (operation.OldColumn.Comment != operation.Comment && operation.Comment != null)
		{
			this.Comment(builder, operation.Comment, operation.Schema, operation.Table, operation.Name);
		}
	}

	private static void DropIdentity(AlterColumnOperation operation, MigrationCommandListBuilder builder)
	{
		Check.NotNull<AlterColumnOperation>(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		string text = $"\nDECLARE\n   v_Count INTEGER;\nBEGIN\n SELECT\n        COUNT(*) INTO v_Count\nFROM\n        SYSCOLUMNS\nWHERE\n        ID =\n        (\n                SELECT\n                        ID\n                FROM\n                        SYSOBJECTS\n                WHERE\n                        NAME    ='{((ColumnOperation)operation).Table}'\n                    AND TYPE$   ='SCHOBJ'\n                    AND SUBTYPE$='UTAB'\n                    AND SCHID   =\n                        (\n                                SELECT ID FROM SYSOBJECTS WHERE NAME = '{((ColumnOperation)operation).Schema}' AND TYPE$='SCH'\n                        )\n        )\n    AND NAME         = '{((ColumnOperation)operation).Name}'\n    AND INFO2 & 0X01 = 1;\n  IF v_Count > 0 THEN\n    EXECUTE IMMEDIATE 'ALTER  TABLE \"{((ColumnOperation)operation).Table}\" DROP IDENTITY';\n  END IF;\nEND;";
		builder.AppendLine(text).EndCommand(false);
	}

	protected override void Generate(RenameIndexOperation operation, IModel model, MigrationCommandListBuilder builder)
	{
		Check.NotNull<RenameIndexOperation>(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		if (operation.NewName != null)
		{
			builder.Append("ALTER INDEX ").Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name)).Append(" RENAME TO ")
				.Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.NewName))
				.Append(this.Dependencies.SqlGenerationHelper.StatementTerminator);
		}
		builder.EndCommand(false);
	}

	protected override void SequenceOptions(string schema, string name, SequenceOperation operation, IModel model, MigrationCommandListBuilder builder)
	{
		Check.NotEmpty(name, "name");
		Check.NotNull<int>(operation.IncrementBy, "IncrementBy");
		Check.NotNull<bool>(operation.IsCyclic, "IsCyclic");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		RelationalTypeMapping mapping = RelationalTypeMappingSourceExtensions.GetMapping(this.Dependencies.TypeMappingSource, typeof(int));
		RelationalTypeMapping mapping2 = RelationalTypeMappingSourceExtensions.GetMapping(this.Dependencies.TypeMappingSource, typeof(long));
		builder.Append(" INCREMENT BY ").Append(mapping.GenerateSqlLiteral(operation.IncrementBy));
		if (operation.MinValue != null)
		{
			builder.Append(" MINVALUE ").Append(mapping2.GenerateSqlLiteral(operation.MinValue));
		}
		else
		{
			builder.Append(" NOMINVALUE");
		}
		if (operation.MaxValue != null)
		{
			builder.Append(" MAXVALUE ").Append(mapping2.GenerateSqlLiteral(operation.MaxValue));
		}
		else
		{
			builder.Append(" NOMAXVALUE");
		}
		builder.Append(operation.IsCyclic ? " CYCLE" : " NOCYCLE");
	}

	protected override void Generate(RenameSequenceOperation operation, IModel model, MigrationCommandListBuilder builder)
	{
		throw new NotSupportedException("RenameSequenceOperation does not support");
	}

	protected override void Generate([NotNull] RestartSequenceOperation operation, [CanBeNull] IModel model, [NotNull] MigrationCommandListBuilder builder)
	{
		throw new NotSupportedException("RestartSequenceOperation does not support");
	}

	protected override void Generate(RenameTableOperation operation, IModel model, MigrationCommandListBuilder builder)
	{
		Check.NotNull<RenameTableOperation>(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		if (operation.NewSchema != null)
		{
			throw new NotSupportedException("RenameTableOperation does not support rename newschema");
		}
		if (operation.NewName != null && operation.NewName != operation.Name)
		{
			builder.Append("ALTER TABLE ").Append((operation.Schema != null) ? this.Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name, operation.Schema) : this.Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name)).Append(" RENAME TO ")
				.Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.NewName))
				.Append(this.Dependencies.SqlGenerationHelper.StatementTerminator)
				.EndCommand(false);
		}
	}

	protected override void Generate(EnsureSchemaOperation operation, IModel model, MigrationCommandListBuilder builder)
	{
		Check.NotNull<EnsureSchemaOperation>(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		builder.Append($"DECLARE\n                    B BOOLEAN ;\n                  BEGIN\n                    SELECT COUNT(NAME) INTO B FROM SYSOBJECTS WHERE TYPE$= 'SCH' AND NAME = '{operation.Name}';\n                    IF B == 0 THEN\n                            EXECUTE IMMEDIATE 'CREATE SCHEMA \"{operation.Name}\" ';\n                    END IF;\n                    END;").EndCommand(false);
	}

	protected virtual void Generate([NotNull] DmCreateUserOperation operation, [CanBeNull] IModel model, [NotNull] MigrationCommandListBuilder builder)
	{
		Check.NotNull(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		builder.Append($"BEGIN\n                             EXECUTE IMMEDIATE 'CREATE USER {operation.UserName} IDENTIFIED BY {operation.Password}';\n                             EXECUTE IMMEDIATE 'GRANT DBA TO {operation.UserName}';\n                             EXECUTE IMMEDIATE 'CREATE SCHEMA {operation.Schema} AUTHORIZATION {operation.UserName}';\n                           END;").EndCommand(true);
	}

	protected virtual void Generate([NotNull] DmDropUserOperation operation, [CanBeNull] IModel model, [NotNull] MigrationCommandListBuilder builder)
	{
		Check.NotNull(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		builder.Append("BEGIN\n                         EXECUTE IMMEDIATE 'DROP USER " + operation.UserName + " CASCADE';\n                       END;").EndCommand(true);
	}

	protected virtual void Generate([NotNull] DmCreateSchemaOperation operation, [CanBeNull] IModel model, [NotNull] MigrationCommandListBuilder builder)
	{
		Check.NotNull(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		builder.Append($"BEGIN\n                        EXECUTE IMMEDIATE 'CREATE SCHEMA {operation.Schema} AUTHORIZATION {operation.UserName}';\n                        END;").EndCommand(true);
	}

	protected virtual void Generate([NotNull] DmDropSchemaOperation operation, [CanBeNull] IModel model, [NotNull] MigrationCommandListBuilder builder)
	{
		Check.NotNull(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		builder.Append("BEGIN\n                         EXECUTE IMMEDIATE 'DROP SCHEMA " + operation.Schema + " CASCADE';\n                       END;").EndCommand(true);
	}

	protected override void Generate([NotNull] CreateIndexOperation operation, [CanBeNull] IModel model, [NotNull] MigrationCommandListBuilder builder, bool terminate = true)
	{
		if (operation.Filter != null)
		{
			throw new NotSupportedException("CreateIndexOperation does not support filter clause");
		}
		base.Generate(operation, model, builder, true);
	}

	protected void Generate(DropIndexOperation operation, IModel model, MigrationCommandListBuilder builder)
	{
		this.Generate(operation, model, builder, true);
	}

	protected override void Generate([NotNull] DropIndexOperation operation, [CanBeNull] IModel model, [NotNull] MigrationCommandListBuilder builder, bool terminate)
	{
		Check.NotNull<DropIndexOperation>(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		builder.Append("DROP INDEX ").Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name));
		if (terminate)
		{
			builder.AppendLine(this.Dependencies.SqlGenerationHelper.StatementTerminator).EndCommand(false);
		}
	}

	protected override void Generate(RenameColumnOperation operation, IModel model, MigrationCommandListBuilder builder)
	{
		Check.NotNull<RenameColumnOperation>(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		StringBuilder stringBuilder = new StringBuilder();
		if (operation.Schema != null)
		{
			stringBuilder.Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Schema)).Append(".");
		}
		stringBuilder.Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Table));
		builder.Append("ALTER TABLE ").Append(stringBuilder.ToString()).Append(" ALTER COLUMN ")
			.Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name))
			.Append(" RENAME TO ")
			.Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.NewName))
			.Append(this.Dependencies.SqlGenerationHelper.StatementTerminator);
		builder.EndCommand(false);
	}

	protected override void Generate(InsertDataOperation operation, IModel model, MigrationCommandListBuilder builder, bool terminate = true)
	{
		Check.NotNull<InsertDataOperation>(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		builder.AppendLine("DECLARE").AppendLine("   CNT  INT;").AppendLine("BEGIN ");
		builder.Append(" SELECT CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END INTO CNT FROM ").Append(" SYSCOLUMNS WHERE ID = (SELECT ID FROM SYSOBJECTS WHERE TYPE$ = 'SCHOBJ' AND SUBTYPE$ = 'UTAB' AND ");
		if (operation.Schema != null)
		{
			builder.Append(" SCHID = (SELECT ID FROM SYS.SYSOBJECTS WHERE TYPE$ = 'SCH' AND NAME = ").Append(RelationalTypeMappingSourceExtensions.GetMapping(this.Dependencies.TypeMappingSource, typeof(string)).GenerateSqlLiteral(operation.Schema)).Append(") AND ");
		}
		else
		{
			builder.Append(" SCHID = CURRENT_SCHID() AND ");
		}
		builder.Append("NAME = ").Append(RelationalTypeMappingSourceExtensions.GetMapping(this.Dependencies.TypeMappingSource, typeof(string)).GenerateSqlLiteral(operation.Table)).AppendLine(" ) AND INFO2&0X01 = 1;");
		builder.AppendLine("IF CNT > 0 THEN ");
		using (builder.Indent())
		{
			builder.Append("EXECUTE IMMEDIATE 'SET IDENTITY_INSERT ").Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Table, operation.Schema)).Append(" ON '")
				.AppendLine(this.Dependencies.SqlGenerationHelper.StatementTerminator);
		}
		builder.AppendLine("END IF; ");
		base.Generate(operation, model, builder, false);
		builder.AppendLine("IF CNT > 0 THEN ");
		using (builder.Indent())
		{
			builder.Append("EXECUTE IMMEDIATE 'SET IDENTITY_INSERT ").Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Table, operation.Schema)).Append(" OFF'")
				.AppendLine(this.Dependencies.SqlGenerationHelper.StatementTerminator);
		}
		builder.AppendLine("END IF; ").AppendLine("END;");
		builder.EndCommand(false);
	}

	protected override void Generate(CreateTableOperation operation, IModel model, MigrationCommandListBuilder builder, bool terminate = true)
	{
		bool flag;
		if (operation.Comment == null)
		{
			flag = operation.Columns.Any((AddColumnOperation c) => c.Comment != null);
		}
		else
		{
			flag = true;
		}
		bool flag2 = flag;
		operation.Columns.ForEach(delegate (AddColumnOperation c)
		{
			if (c.ColumnType != null)
			{
				if (c.ColumnType.StartsWith("DOUBLE PRECISION", StringComparison.OrdinalIgnoreCase))
				{
					c.ColumnType = "DOUBLE PRECISION";
					return;
				}
				if (c.ColumnType.StartsWith("ROWID", StringComparison.OrdinalIgnoreCase))
				{
					c.ColumnType = "ROWID";
				}
			}
		});
		if (!flag2)
		{
			base.Generate(operation, model, builder, true);
		}
		else
		{
			if (!terminate)
			{
				throw new NotSupportedException("can not Produce Unterminated SQL With Comments");
			}
			base.Generate(operation, model, builder, true);
			if (flag2)
			{
				if (operation.Comment != null)
				{
					this.Comment(builder, operation.Comment, operation.Schema, operation.Name, null);
				}
				foreach (AddColumnOperation addColumnOperation in operation.Columns)
				{
					if (addColumnOperation.Comment != null)
					{
						this.Comment(builder, addColumnOperation.Comment, operation.Schema, operation.Name, addColumnOperation.Name);
					}
				}
			}
		}
		AddColumnOperation[] array = operation.Columns.Where((AddColumnOperation c) => c.IsRowVersion).ToArray<AddColumnOperation>();
		if (array.Length != 0)
		{
			builder.Append("CREATE OR REPLACE TRIGGER ").AppendLine(this.Dependencies.SqlGenerationHelper.DelimitIdentifier("rowversion_" + operation.Name, operation.Schema)).Append("BEFORE INSERT OR UPDATE ON ")
				.AppendLine(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name, operation.Schema))
				.AppendLine("FOR EACH ROW")
				.AppendLine("BEGIN");
			foreach (AddColumnOperation addColumnOperation2 in array)
			{
				builder.Append("  :NEW.").Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(addColumnOperation2.Name)).Append(" := NVL(:OLD.")
					.Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(addColumnOperation2.Name))
					.Append(", '00000000') + 1")
					.AppendLine(this.Dependencies.SqlGenerationHelper.StatementTerminator);
			}
			builder.Append("END").AppendLine(this.Dependencies.SqlGenerationHelper.StatementTerminator);
		}
		this.EndStatement(builder, false);
	}

	protected override void UniqueConstraint([NotNull] AddUniqueConstraintOperation operation, [CanBeNull] IModel model, [NotNull] MigrationCommandListBuilder builder)
	{
		Check.NotNull<AddUniqueConstraintOperation>(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		if (operation.Name == null)
		{
			operation.Name = Guid.NewGuid().ToString();
		}
		base.UniqueConstraint(operation, model, builder);
	}

	protected override void ColumnDefinition([CanBeNull] string schema, [NotNull] string table, [NotNull] string name, ColumnOperation operation, [CanBeNull] IModel model, [NotNull] MigrationCommandListBuilder builder)
	{
		Check.NotEmpty(name, "name");
		Check.NotNull<ColumnOperation>(operation, "operation");
		Check.NotNull<Type>(operation.ClrType, "ClrType");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		if (operation.ComputedColumnSql != null)
		{
			builder.Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(name)).Append(" AS (").Append(operation.ComputedColumnSql)
				.Append(")");
			return;
		}
		builder.Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(name)).Append(" ").Append(operation.ColumnType ?? this.GetColumnType(schema, table, name, operation, model));
		string text = operation["Dm:Identity"] as string;
		if (text != null || (operation["Dm:ValueGenerationStrategy"] as DmValueGenerationStrategy?).GetValueOrDefault() == DmValueGenerationStrategy.IdentityColumn)
		{
			builder.Append(" IDENTITY");
			if (!string.IsNullOrEmpty(text) && text != "1, 1")
			{
				builder.Append("(").Append(text).Append(")");
			}
		}
		else
		{
			this.DefaultValue(operation.DefaultValue, operation.DefaultValueSql, operation.ColumnType, builder);
		}
		builder.Append(operation.IsNullable ? " NULL" : " NOT NULL");
	}

	protected override void PrimaryKeyConstraint([NotNull] AddPrimaryKeyOperation operation, [CanBeNull] IModel model, [NotNull] MigrationCommandListBuilder builder)
	{
		Check.NotNull<AddPrimaryKeyOperation>(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		if (operation.Name == null)
		{
			operation.Name = Guid.NewGuid().ToString();
		}
		base.PrimaryKeyConstraint(operation, model, builder);
	}

	protected override void ForeignKeyConstraint(AddForeignKeyOperation operation, IModel model, MigrationCommandListBuilder builder)
	{
		Check.NotNull<AddForeignKeyOperation>(operation, "operation");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		if (operation.PrincipalColumns == null)
		{
			throw new NotSupportedException("AddForeignKeyOperation does not support references columns is null");
		}
		if (operation.Name == null)
		{
			operation.Name = Guid.NewGuid().ToString();
		}
		base.ForeignKeyConstraint(operation, model, builder);
	}

	protected virtual void DropDefaultConstraint([CanBeNull] string schema, [NotNull] string tableName, [NotNull] string columnName, [NotNull] MigrationCommandListBuilder builder)
	{
		Check.NotEmpty(tableName, "tableName");
		Check.NotEmpty(columnName, "columnName");
		Check.NotNull<MigrationCommandListBuilder>(builder, "builder");
		builder.Append("ALTER TABLE ").Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(tableName, schema)).Append(" MODIFY ")
			.Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(columnName))
			.Append(" DEFAULT NULL")
			.AppendLine(this.Dependencies.SqlGenerationHelper.StatementTerminator)
			.EndCommand(false);
	}

	protected override void Generate(AddColumnOperation operation, IModel? model, MigrationCommandListBuilder builder, bool terminate)
	{
		if (operation.Comment == null)
		{
			base.Generate(operation, model, builder, terminate);
			return;
		}
		if (!terminate)
		{
			throw new NotSupportedException("can not Produce Unterminated SQL With Comments");
		}
		base.Generate(operation, model, builder, true);
		this.Comment(builder, operation.Comment, operation.Schema, operation.Table, operation.Name);
	}

	protected override void Generate(AlterTableOperation operation, IModel? model, MigrationCommandListBuilder builder)
	{
		base.Generate(operation, model, builder);
		if (operation.OldTable.Comment != operation.Comment && operation.Comment != null)
		{
			this.Comment(builder, operation.Comment, operation.Schema, operation.Name, null);
			builder.EndCommand(false);
		}
	}

	protected virtual void Comment(MigrationCommandListBuilder builder, string description, string? schema, string table, string? column = null)
	{
		if (column != null)
		{
			builder.Append("comment on column ");
		}
		else
		{
			builder.Append("comment on table ");
		}
		builder.Append(this.Dependencies.SqlGenerationHelper.DelimitIdentifier(table, schema));
		if (column != null)
		{
			builder.Append("." + this.Dependencies.SqlGenerationHelper.DelimitIdentifier(column));
		}
		builder.Append(" is ");
		builder.Append("'" + description.Replace("'", "''") + "'");
		builder.AppendLine(this.Dependencies.SqlGenerationHelper.StatementTerminator);
		builder.EndCommand(false);
	}
}
